﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using FMSpaceShooter.GameData;
using FMSpaceShooter.GameObjects;
using FMSpaceShooter.Screens;
using System.IO;

namespace FMSpaceShooter.GameObjects
{
    class GameEvent
    {
        public TimeSpan When;
        public string What;
        public Vector2 Where;
    }

    class Level 
    {
        TimeSpan? levelStart = null;
        List<GameEvent> gameEvents = new List<GameEvent>();

        GameplayScreen screen;

        private const string levelLocation = "Levels/";
        public int enemyCount { get { return eCount; } set { eCount=value; } }
        private int eCount;
        public bool isFinished { get { return levelFinished; } set { levelFinished = value; } }
        private bool levelFinished;
        private static double timeLeft = -1;

        public static TimeSpan TimeLeft { get { return TimeSpan.FromMilliseconds(timeLeft); } }

        public Level(GameplayScreen screen, int id)
        {
            this.screen = screen;
            eCount = 0;
            levelFinished = false;
            string[] lines = File.ReadAllLines(string.Format(levelLocation + "{0}.txt", id.ToString("D2")));
            try
            {
                foreach (string line in lines)
                {
                    string[] parts = line.Split('\t');
                    float[] vectorParts = parts[2].Split(',').Select(s => float.Parse(s)).ToArray();
                    var ge = new GameEvent
                    {
                        When = TimeSpan.FromMilliseconds(int.Parse(parts[0])),
                        What = parts[1],
                        Where = new Vector2(vectorParts[0], vectorParts[1])
                    };
                    gameEvents.Add(ge);
                    eCount++;
                }
                System.Console.Out.WriteLine(eCount);
            }
            catch (Exception ex)
            {
                throw new Exception("Error Loading Level " + id, ex);
            }
        }


        public void Update(GameTime gameTime)
        {
            if (levelStart == null)
            {
                levelStart = gameTime.TotalGameTime;
            }
            Vector2 res = new Vector2(screen.GraphicsDeviceManager.PreferredBackBufferWidth,
                screen.GraphicsDeviceManager.PreferredBackBufferHeight);

            TimeSpan levelTime = (gameTime.TotalGameTime - (TimeSpan)levelStart);
            // change for really big levels
            var activeEvents = gameEvents.Where(e => e.When < levelTime).ToList();

            foreach (var ge in activeEvents)
            {
                gameEvents.Remove(ge);

                screen.GOM.AddToPlay(Factories.BadGuyFactory(screen, ge.What, ge.Where * res));
                // add object to play
            }
            timeLeft -= gameTime.ElapsedGameTime.Milliseconds;
            if (timeLeft < 0 || enemyCount<1)
            {
                levelFinished = true;
            }

        }

        public static void createRandomLevel(int difficulty)
        {

            List<string> enemyTypes = new List<string> { "FirstEnemy", "OrbitalEnemy", "CantCatchMeEnemy", "Boss1","TeleporterEnemy" };
            Dictionary<string, int> enemyTypesWillToSurvive;
            switch (difficulty)
            {
                case 1:
                    enemyTypesWillToSurvive=new Dictionary<string, int> { { "FirstEnemy", 20 }};
                    break;
                case 2:
                    enemyTypesWillToSurvive = new Dictionary<string, int> { { "FirstEnemy", 20 }, { "OrbitalEnemy", 5  } };
                    break;
                case 3:
                    enemyTypesWillToSurvive = new Dictionary<string, int> { { "FirstEnemy", 20 }, { "OrbitalEnemy", 5  }, { "CantCatchMeEnemy", 5  } };
                    break;
                case 4:
                    enemyTypesWillToSurvive = new Dictionary<string, int> { { "FirstEnemy", 20 }, { "OrbitalEnemy", 5 }, { "CantCatchMeEnemy", 5 }, { "Boss1", 1 } };
                    break;
                default:
                    enemyTypesWillToSurvive = new Dictionary<string, int> { { "FirstEnemy", 40 + (difficulty) }, { "OrbitalEnemy", 5 + (difficulty * 2) }, { "CantCatchMeEnemy", 5 + (difficulty * 2) }, { "Boss1", 1 + difficulty  }, {"TeleporterEnemy", 4+difficulty} };
                    break;

            }
           // Dictionary<string, int> enemyTypesWillToSurvive = new Dictionary<string, int> { { "FirstEnemy", 20 }, { "OrbitalEnemy", 5 }, { "CantCatchMeEnemy", 5 }, { "Boss1", 1 } };
            int totalWill = enemyTypesWillToSurvive.Sum(s => s.Value);


            StringBuilder sb = new StringBuilder();
            Random rand = new Random();
            //adjusted for longer gameplay
            for (int i = 0; i < 10*difficulty+rand.Next(10*difficulty); i++)
            {
                int type = rand.Next(4);
                int enemyRand = rand.Next(totalWill);
                int enemyType = 0;
                for (; enemyType < enemyTypes.Count && enemyRand > enemyTypesWillToSurvive[enemyTypes[enemyType]]; enemyType++)
                {
                    enemyRand -= enemyTypesWillToSurvive[enemyTypes[enemyType]];
                }


                sb.AppendLine(string.Format("{0}\t{1}\t{2},{3}",
                    4000 + rand.Next(10000 * difficulty),
                    enemyTypes[enemyType],
                    (type == 0 ? 1 : (type == 1 ? 0 : (float)rand.NextDouble())),
                    (type == 2 ? 1 : (type == 3 ? 0 : (float)rand.NextDouble()))
                    ));
            }
            timeLeft = 15000 * difficulty;
            System.IO.File.WriteAllText("Levels/-999.txt", sb.ToString());
        }
    }

}
